/***************************************************************************
 *   This is a part of the NextCAD Web APP.                                *
 *   Copyright (C) AMCAX, All rights reserved.                             *
 ***************************************************************************/
/*
 * @Descripttion:
 * @version: 1.0.0
 * @Author: YinJianFeng
 * @Date: 2024-03-29 16:21:50
 */
import { KEYBOARD_KEY } from '@app-cad/common/Constants';
import { wsApi } from '@app-cad/server';

import {
  BaseCommand,
  CENTEREVENTS,
  CMEVENTS,
  EventsRes,
  MouseStyle,
  PickedFace,
} from '@amcax/base';
import { Picker3D, PickerMgr } from '@amcax/renderer';
import { eventCenterManager } from '@app-base/common/events/EventCenterManager';
import { dataManager, userEvents } from '@app-cad/module';

enum State {
  PICK,
  DRAW,
}

let currentState: State = State.PICK;
let materialId = undefined;
let materialBox = undefined;
let targetObject: any = undefined;

// 取色刷
const fnColorBrush = () => {
  materialBox = document.getElementById('material-box');

  // 注册鼠标键盘
  eventCenterManager.activeEventCenter
    .setState('color-brush')
    .on(CENTEREVENTS.KEYUP, keyupEvent)
    .on(CENTEREVENTS.POINTERUP, onMouseClick)
    .on(CENTEREVENTS.POINTERMOVE, onMouseMove)
    .addExit(fnDestory);
  MouseStyle.setImg('materialPick', 8, 20);

  return null;
};

function keyupEvent(e: EventsRes<KeyboardEvent>) {
  if (e.key === KEYBOARD_KEY.ESC) {
    fnDestory();
  }
}

async function onMouseClick() {
  if (materialId != undefined) {
    if (currentState === State.PICK) {
      currentState = State.DRAW;
      MouseStyle.setImg('materialBrush', 10, 16);

      const material = dataManager.getMaterials(materialId);
      if (material) {
        // 显示鼠标提示框
        materialBox.style.visibility = 'visible';
        materialBox.style.background = material.color;
      }
    } else if (currentState === State.DRAW) {
      if (targetObject) {
        const assisObj = targetObject.assisObj;
        const dxid = targetObject.idInfo.o;
        let faceIndex = -1;
        if (assisObj instanceof PickedFace) {
          faceIndex = targetObject.idInfo.i;
        }
        await wsApi.setMaterials(dxid, faceIndex, materialId);
      }
      fnDestory();
    }
  }
}

function onMouseMove(e: EventsRes) {
  if (e.button.buttonDown) {
    return;
  }
  if (currentState === State.PICK) {
    materialId = PickerMgr.getPicker<Picker3D>('3d').pickMaterial(e);
  } else if (currentState === State.DRAW) {
    materialBox.style.left = e.mouse.x + 18 + 'px';
    materialBox.style.top = e.mouse.y - 42 + 'px';
    const pickRes = PickerMgr.getPicker<Picker3D>('3d').pick(e, {});
    targetObject = pickRes;
  }
}

const fnDestory = () => {
  eventCenterManager.activeEventCenter
    .off(CENTEREVENTS.POINTERMOVE, onMouseMove)
    .off(CENTEREVENTS.POINTERUP, onMouseClick)
    .off(CENTEREVENTS.KEYUP, keyupEvent)
    .setDefault();
  MouseStyle.setImg('');
  materialBox.style.visibility = 'hidden';
  currentState = State.PICK;
  materialId = undefined;
  targetObject = undefined;
  userEvents.emit(CMEVENTS.CMD_FINISHED, cmdColorBrush);
};

export const cmdColorBrush: BaseCommand = {
  id: 'CmdColorBrush',
  label: 'command.bim.colorBrush',
  icon: 'commands/feature/material-brush',
  invoke: fnColorBrush,
  destory: fnDestory,
};
